package com.ltg.framework.mybatis.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.ltg.framework.mybatis.entity.BaseEntity;
import com.ltg.framework.mybatis.help.PageResult;
import com.ltg.framework.mybatis.help.QMap;
import com.ltg.framework.mybatis.mapper.PlusMapper;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;

/**
 * nekoimi  2021/12/18 13:59
 * <p>
 * CRUD service interface
 * @author 24957
 */
public interface IPlusService<E extends BaseEntity> {
    /**
     * <p>雪花算法唯一键</p>
     *
     * @return
     */
    String primaryKeyId();

    /**
     * =====================================
     * 模型信息
     * =====================================
     */
    Class<E> currentModelClass();

    Class<? extends PlusMapper<E>> currentMapperClass();

    PlusMapper<E> currentMapper();

    TableInfo currentTableInfo();

    Serializable currentPrimaryKeyProperty();

    Field currentPrimaryKeyField();

    List<TableFieldInfo> currentTableFieldList();

    /**
     * =====================================
     * 查询对象
     * =====================================
     */
    QMap<SFunction<E, Object>, Object> newQMap();

    QueryWrapper<E> newQuery();

    LambdaQueryWrapper<E> newLambdaQuery();

    LambdaUpdateWrapper<E> newLambdaUpdate();

    /**
     * =====================================
     * CRUD 查询接口
     * =====================================
     */
    E getById(Serializable id);

    E getByQuery(Consumer<LambdaQueryWrapper<E>> consumer);

    E getByMap(Consumer<QMap<SFunction<E, Object>, Object>> consumer);

    E getOf(SFunction<E, Object> k1, Object v1);

    E getOf(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2);

    E getOf(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3);

    E getOf(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4);

    E getOf(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5);

    E getOf(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5, SFunction<E, Object> k6, Object v6);

    E getOf(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5, SFunction<E, Object> k6, Object v6, SFunction<E, Object> k7, Object v7);

    E getOf(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5, SFunction<E, Object> k6, Object v6, SFunction<E, Object> k7, Object v7, SFunction<E, Object> k8, Object v8);

    E getOf(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5, SFunction<E, Object> k6, Object v6, SFunction<E, Object> k7, Object v7, SFunction<E, Object> k8, Object v8, SFunction<E, Object> k9, Object v9);

    E getOf(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5, SFunction<E, Object> k6, Object v6, SFunction<E, Object> k7, Object v7, SFunction<E, Object> k8, Object v8, SFunction<E, Object> k9, Object v9, SFunction<E, Object> k10, Object v10);

    E getByIdOrFail(Serializable id);

    E getByQueryOrFail(Consumer<LambdaQueryWrapper<E>> consumer);

    E getByMapOrFail(Consumer<QMap<SFunction<E, Object>, Object>> consumer);

    E getOfOrFail(SFunction<E, Object> k1, Object v1);

    E getOfOrFail(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2);

    E getOfOrFail(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3);

    E getOfOrFail(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4);

    E getOfOrFail(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5);

    E getOfOrFail(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5, SFunction<E, Object> k6, Object v6);

    E getOfOrFail(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5, SFunction<E, Object> k6, Object v6, SFunction<E, Object> k7, Object v7);

    E getOfOrFail(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5, SFunction<E, Object> k6, Object v6, SFunction<E, Object> k7, Object v7, SFunction<E, Object> k8, Object v8);

    E getOfOrFail(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5, SFunction<E, Object> k6, Object v6, SFunction<E, Object> k7, Object v7, SFunction<E, Object> k8, Object v8, SFunction<E, Object> k9, Object v9);

    E getOfOrFail(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5, SFunction<E, Object> k6, Object v6, SFunction<E, Object> k7, Object v7, SFunction<E, Object> k8, Object v8, SFunction<E, Object> k9, Object v9, SFunction<E, Object> k10, Object v10);

    Boolean exists(Serializable id);

    Boolean existsOf(SFunction<E, Object> k1, Object v1);

    Boolean existsByQuery(Consumer<LambdaQueryWrapper<E>> consumer);

    Boolean existsByMap(Consumer<QMap<SFunction<E, Object>, Object>> consumer);

    Serializable save(E entity);

    Serializable saveMap(Map<String, Object> map);

    void saveBatch(List<E> entityList);

    Serializable saveOrUpdate(E entity);

    Boolean update(E entity);

    void updateBatch(String ids, Map<String, Object> map);

    void updateBatch(List<? extends Serializable> idList, Map<String, Object> map);

    Boolean updateByQuery(E entity, Consumer<LambdaUpdateWrapper<E>> consumer);

    Boolean updateById(Serializable id, E e);

    Boolean updateById(Serializable id, Consumer<LambdaUpdateWrapper<E>> consumer);

    Boolean updateByIdOfMap(Serializable id, Map<String, Object> map);

    Boolean updateByIdOfMap(Serializable id, Consumer<QMap<SFunction<E, Object>, Object>> consumer);

    Boolean updateOf(Serializable id, SFunction<E, Object> k1, Object v1);

    Boolean updateOf(Serializable id, SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2);

    Boolean updateOf(Serializable id, SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3);

    Boolean updateOf(Serializable id, SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4);

    Boolean updateOf(Serializable id, SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5);

    Boolean updateOf(Serializable id, SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5, SFunction<E, Object> k6, Object v6);

    Boolean updateOf(Serializable id, SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5, SFunction<E, Object> k6, Object v6, SFunction<E, Object> k7, Object v7);

    Boolean updateOf(Serializable id, SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5, SFunction<E, Object> k6, Object v6, SFunction<E, Object> k7, Object v7, SFunction<E, Object> k8, Object v8);

    Boolean updateOf(Serializable id, SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5, SFunction<E, Object> k6, Object v6, SFunction<E, Object> k7, Object v7, SFunction<E, Object> k8, Object v8, SFunction<E, Object> k9, Object v9);

    Boolean updateOf(Serializable id, SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5, SFunction<E, Object> k6, Object v6, SFunction<E, Object> k7, Object v7, SFunction<E, Object> k8, Object v8, SFunction<E, Object> k9, Object v9, SFunction<E, Object> k10, Object v10);

    void removeById(Serializable id);

    void removeByQuery(Consumer<LambdaQueryWrapper<E>> consumer);

    void removeBatch(String ids);

    void removeBatch(List<? extends Serializable> idList);

    long countAll();

    long countByQuery(Consumer<LambdaQueryWrapper<E>> consumer);

    long countByMap(Consumer<QMap<SFunction<E, Object>, Object>> consumer);

    List<E> findAll();

    List<E> findByIds(List<? extends Serializable> ids);

    List<E> findByQuery(Consumer<LambdaQueryWrapper<E>> consumer);

    List<E> findByMap(Consumer<QMap<SFunction<E, Object>, Object>> consumer);

    @SuppressWarnings("unchecked")
    List<E> findAllSelectColumn(SFunction<E, Object>... columns);

    @SuppressWarnings("unchecked")
    List<E> findByQuerySelectColumn(Consumer<LambdaQueryWrapper<E>> consumer, SFunction<E, Object>... columns);

    @SuppressWarnings("unchecked")
    List<E> findByMapSelectColumn(Consumer<QMap<SFunction<E, Object>, Object>> consumer, SFunction<E, Object>... columns);

    List<E> findOf(SFunction<E, Object> k1, Object v1);

    List<E> findOf(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2);

    List<E> findOf(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3);

    List<E> findOf(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4);

    List<E> findOf(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5);

    List<E> findOf(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5, SFunction<E, Object> k6, Object v6);

    List<E> findOf(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5, SFunction<E, Object> k6, Object v6, SFunction<E, Object> k7, Object v7);

    List<E> findOf(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5, SFunction<E, Object> k6, Object v6, SFunction<E, Object> k7, Object v7, SFunction<E, Object> k8, Object v8);

    List<E> findOf(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5, SFunction<E, Object> k6, Object v6, SFunction<E, Object> k7, Object v7, SFunction<E, Object> k8, Object v8, SFunction<E, Object> k9, Object v9);

    List<E> findOf(SFunction<E, Object> k1, Object v1, SFunction<E, Object> k2, Object v2, SFunction<E, Object> k3, Object v3, SFunction<E, Object> k4, Object v4, SFunction<E, Object> k5, Object v5, SFunction<E, Object> k6, Object v6, SFunction<E, Object> k7, Object v7, SFunction<E, Object> k8, Object v8, SFunction<E, Object> k9, Object v9, SFunction<E, Object> k10, Object v10);

    PageResult<E> page(IPage<E> page);

    @SuppressWarnings("unchecked")
    PageResult<E> page(IPage<E> page, SFunction<E, Object>... columns);

    PageResult<E> page(IPage<E> page, Consumer<LambdaQueryWrapper<E>> consumer);

    int insert(Map<String, Object> map);

    int deleteById(Serializable id);

    int deleteByMap(Map<String, Object> columnMap);

    int deleteBatchIds(Collection<? extends Serializable> idList);

    int updateById(Serializable id, Map<String, Object> columnMap);

    Map<String, Object> selectById(Serializable id);

    List<Map<String, Object>> selectBatchIds(Collection<? extends Serializable> idList);

    List<Map<String, Object>> selectByMap(Map<String, Object> columnMap);

    Integer selectCount(Map<String, Object> columnMap);

    List<Map<String, Object>> selectList(Map<String, Object> columnMap);

    IPage<Map<String, Object>> selectListPage(IPage<Map<String, Object>> page, Map<String, Object> columnMap);

    Integer updateAndSave(List<E> entities) ;

}

